﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace OpenApiExtensions
{
    public static class EnumExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public static string ToDescription(this Enum item)
        {
            string name = item.ToString();
            var desc = item.GetType().GetField(name)?.GetCustomAttribute<DescriptionAttribute>();
            return desc?.Description ?? name;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public static string ToDisplayName(this Enum item)
        {
            string name = item.ToString();
            var desc = item.GetType().GetField(name)?.GetCustomAttribute<DisplayAttribute>();
            return desc?.Name ?? name;
        }
       /* /// <summary>
        /// 
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public static string ToSummary(this Enum item)
        {
            string name = item.ToString();
            return item.GetType().GetField(name)?.GetXmlDocumentation() ?? "";
        }*/
        public static long ToInt64(this Enum item)
        {
            return Convert.ToInt64(item);
        }

     /*   public static List<OptionDTO> ToList(this Enum value, bool ignoreUnKnown = false)
        {
            var enumType = value.GetType();

            if (!enumType.IsEnum)
                return null;
            Array Values = Enum.GetValues(enumType);

            return Values.Cast<Enum>()
                .Where(m => !ignoreUnKnown || !m.ToString().Equals("UnKnown"))
                .Select(x => new OptionDTO
                {
                    Data = x.ToSummary(),
                    Label = x.ToDescription(),
                    Value = x,// (int)x
                }).ToList();
        }*/

        /// <summary>
        /// 枚举转字典（需获取描述时使用）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static IDictionary<int, string> EnumToDictionary<T>() where T : System.Enum
        {
            Type type = typeof(T);

            string[] Names = System.Enum.GetNames(type);

            Array Values = System.Enum.GetValues(type);

            IDictionary<int, string> dic = new Dictionary<int, string>();

            string desc = string.Empty;

            for (int i = 0; i < Values.Length; i++)
            {
                T t = (T)System.Enum.Parse(typeof(T), Values.GetValue(i).ToString());

                MemberInfo[] memInfo = type.GetMember(t.ToString());

                if (memInfo != null && memInfo.Length > 0)
                {
                    object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                    if (attrs != null && attrs.Length > 0)
                    {
                        desc = ((DescriptionAttribute)attrs[0]).Description;
                    }
                }
                //GetEnumDesc(T);

                dic.Add((int)Values.GetValue(i), string.IsNullOrEmpty(desc) ? Names[i].ToString() : desc);
            }

            return dic;
        }


      /*  /// <summary>
        ///  返回说明
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static List<OptionDTO> EnumToList<T>() where T : System.Enum
        {
            Type type = typeof(T);

            string[] Names = System.Enum.GetNames(type);

            Array Values = System.Enum.GetValues(type);

            List<OptionDTO> dic = new List<OptionDTO>();

            string desc = string.Empty;

            for (int i = 0; i < Values.Length; i++)
            {
                T t = (T)System.Enum.Parse(typeof(T), Values.GetValue(i).ToString());

                MemberInfo[] memInfo = type.GetMember(t.ToString());

                if (memInfo != null && memInfo.Length > 0)
                {
                    object[] attrs = memInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);
                    if (attrs != null && attrs.Length > 0)
                    {
                        desc = ((DisplayAttribute)attrs[0]).Name;
                    }
                    else
                    {
                        var dattrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                        if (dattrs != null && dattrs.Length > 0)
                        {
                            desc = ((DescriptionAttribute)dattrs[0]).Description;
                        }
                        else
                            desc = memInfo[0].GetXmlDocumentation() ?? "";
                    }
                }
                //GetEnumDesc(T);
                dic.Add(new OptionDTO
                {
                    Value = (int)Values.GetValue(i),
                    Label = string.IsNullOrEmpty(desc) ? Names[i].ToString() : desc,
                    Data = Names[i].ToString(),
                    Disabled = false,
                });
            }

            return dic;
        }
       */
        
        /// <summary>
        /// 枚举转字典(无需获取描述时使用)
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IDictionary<int, string> EnumToDictionary(Type type)
        {
            string[] Names = System.Enum.GetNames(type);

            Array Values = System.Enum.GetValues(type);

            IDictionary<int, string> dic = new Dictionary<int, string>();

            for (int i = 0; i < Values.Length; i++)
            {
                dic.Add((int)Values.GetValue(i), Names[i].ToString());
            }

            return dic;
        }
      /*  public static List<OptionDTO> ToList<T>(bool ignoreUnKnown = false) where T : System.Enum
        {
            var enumType = typeof(T);

            if (!enumType.IsEnum)
                return null;

            return Enum.GetValues(enumType).Cast<Enum>()
                 .Where(m => !ignoreUnKnown || !m.ToString().Equals("UnKnown"))
                 .Select(x => new OptionDTO
                 {
                     Data = x.ToDescription(),
                     Label = x.ToDisplayName(),
                     Value = x
                 }).ToList();
        }*/
    }
}
